home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin / F2JW / trans / load.cpp < prev    next >
C/C++ Source or Header  |  1999-12-31  |  19KB  |  719 lines

  1. //
  2. // f2j 辞書をファイルからロードする
  3. //
  4.  
  5. #include "stdafx.h"
  6. #include    <string.h>
  7. #include    <ctype.h>
  8.  
  9.  
  10. #include    "f2j.h"
  11. #include    "myprot.h"
  12.  
  13. extern    char        *tokenPtr;
  14. extern    NOUN        *nounTable;
  15. extern    ADJECTIVE    *adjectiveTable;
  16. extern    ADVERB        *adverbTable;
  17.  
  18. char    inputBuff[300];
  19.  
  20. //
  21. // 名詞辞書をload
  22. //
  23. void
  24. LoadNounTable(char *fn)
  25. {
  26.     FILE    *fp;
  27.     NOUN    *noun;
  28.  
  29.     fp = fopen(fn, "rt");
  30.     if((int )fp <= 0) {
  31.         PrintInternalError( "Can not open <%s>\nThis file must be in the same direcotry.", fn);
  32.         exit(-1);
  33.     } else {
  34.         while(TRUE) {
  35.             fgets(inputBuff, sizeof(inputBuff), fp);
  36.             if(feof(fp))    break;
  37.             tokenPtr = inputBuff;
  38.             noun = GetNounWord();
  39.             SetNounWord(noun);
  40.         }
  41.     }
  42.     fclose(fp);
  43. }
  44.  
  45. //
  46. //
  47. //
  48. NOUN
  49. *GetNounWord(void )
  50. {
  51.     FR_PART        dummyFrPart;
  52.     JP_KIND        dummyJpKind;
  53.     FR_LOCATION    dummyLocation;
  54.     JP_UNIT        dummyUnit;
  55.     int        i;
  56.  
  57.     NOUN    *noun = (NOUN *)MyAlloc(sizeof(NOUN));
  58.  
  59.     noun->left = noun->right = NULL;
  60.     noun->frAttrib = FR_ATTRIB_NONE;
  61.     noun->frChange = FR_CHANGE_NONE;
  62.     noun->french = NewString();
  63. //    GetFrInfo(&(noun->frAttrib), &(noun->frChange));
  64.  
  65.     noun->proposed = CountComma(tokenPtr)/4+1;
  66.     noun->jpNoun   = (JP_NOUN *)MyAlloc(sizeof(JP_NOUN) * noun->proposed);
  67.     for(i = 0; i < noun->proposed; i++) {
  68.         GetFrInfo(&(noun->jpNoun[i].frAttrib),
  69.                   &(noun->jpNoun[i].frChange));
  70.         if(noun->jpNoun[i].frAttrib == FR_ATTRIB_NONE) {
  71.             // 指定無し
  72.             if(i == 0) {
  73.                 // デフォルトの設定
  74.                 noun->jpNoun[i].frAttrib = FR_ATTRIB_MALE;
  75.                 noun->jpNoun[i].frChange = FR_CHANGE_PLURAL;
  76.             } else {
  77.                 // 前の候補の設定
  78.                 noun->jpNoun[i].frAttrib = noun->jpNoun[i-1].frAttrib;
  79.                 noun->jpNoun[i].frChange = noun->jpNoun[i-1].frChange;
  80.             }
  81.         }
  82.         if(noun->jpNoun[i].frChange & FR_CHANGE_PLURAL) {
  83.             FR_CHANGE frChange = GetPluralType(noun->french);
  84.             if(frChange == FR_CHANGE_NONE) {    // 単複同形名詞
  85.                 noun->jpNoun[i].frAttrib = (FR_ATTRIB)(noun->jpNoun[i].frAttrib | FR_ATTRIB_SINGLE | FR_ATTRIB_PLURAL);
  86.             } else {
  87.                 noun->jpNoun[i].frChange = (FR_CHANGE)(noun->jpNoun[i].frChange | frChange);
  88.             }
  89.         }
  90.         noun->frAttrib = (FR_ATTRIB)(noun->frAttrib | noun->jpNoun[i].frAttrib);
  91.         noun->frChange = (FR_CHANGE)(noun->frChange | noun->jpNoun[i].frChange);
  92.  
  93.         noun->jpNoun[i].cFrPart = FR_PART_NONE;
  94.         noun->jpNoun[i].cJpProp = JP_PROP_NONE;
  95.         GetJpInfo(&(noun->jpNoun[i].cFrPart),
  96.                   &(noun->jpNoun[i].cJpProp),
  97.                   &dummyJpKind,
  98.                   &dummyUnit,
  99.                   &dummyLocation);
  100.         if(noun->jpNoun[i].cFrPart != FR_PART_NONE
  101.         && noun->jpNoun[i].cJpProp == JP_PROP_NONE)
  102.             noun->jpNoun[i].cJpProp = JP_PROP_ALL;
  103.  
  104.         noun->jpNoun[i].japanese = NewString();
  105.         noun->jpNoun[i].jpProp = JP_PROP_NONE;
  106.         noun->jpNoun[i].jpUnit = JP_UNIT_NONE;
  107.         GetJpInfo(&dummyFrPart,
  108.                   &(noun->jpNoun[i].jpProp),
  109.                   &dummyJpKind,
  110.                   &(noun->jpNoun[i].jpUnit),
  111.                   &dummyLocation);
  112.     }
  113.     // default settings <事柄>
  114.     i--;
  115.     if(!(noun->jpNoun[i].jpProp 
  116.     & (JP_PROP_ACTION    | JP_PROP_CONDITION    | JP_PROP_HUMAN
  117.     |  JP_PROP_PLACE    | JP_PROP_QUESTION    | JP_PROP_TIME
  118.     |  JP_PROP_UNIT))) {
  119.         noun->jpNoun[i].jpProp = (JP_PROP)(noun->jpNoun[i].jpProp | JP_PROP_THING);
  120.     }
  121.     return(noun);
  122. }
  123.  
  124. //
  125. // 名詞を新しい辞書に追加
  126. //
  127. void
  128. SetNounWord(NOUN *newNoun)
  129. {
  130.     if(nounTable == NULL) {    // 最初の単語
  131.         nounTable = newNoun;
  132.         return;
  133.     }
  134.  
  135.     tokenPtr = newNoun->french;
  136.     NOUN    *p = nounTable;
  137.     while(p) {
  138.         CMP_WORD cmp = CompareNoun(p->french, FR_CHANGE_NONE);
  139.         if(cmp & CMP_WORD_LEFT)    {
  140.             if(p->left) { p = p->left; continue; }
  141.             else        { p->left = newNoun; break;    }
  142.         } else if(cmp & CMP_WORD_RIGHT){
  143.             if(p->right){ p = p->right; continue; }
  144.             else        { p->right = newNoun; break; }
  145.         } else {
  146. //            PrintInternalError( "Multiple Definition on <%s> in f2j_noun.dic\n", newNoun->french);
  147.         }
  148.     }
  149. }
  150.  
  151.  
  152. JP_UNIT_INFO    jpUnitInforTable[] =
  153. {    JP_UNIT_INFO( "行",    JP_PROP_ACTION,        JP_UNIT_NONE    ),    // 行動
  154.     JP_UNIT_INFO( "状",    JP_PROP_CONDITION,    JP_UNIT_NONE    ),    // 状態
  155.     JP_UNIT_INFO( "人", JP_PROP_HUMAN,        JP_UNIT_HITO    ),
  156.     JP_UNIT_INFO( "場", JP_PROP_PLACE,        JP_UNIT_NONE    ),
  157.     JP_UNIT_INFO( "物", JP_PROP_THING,        JP_UNIT_NONE    ),
  158.     JP_UNIT_INFO( "抽", JP_PROP_ABSTRACT,    JP_UNIT_NONE    ),
  159.     JP_UNIT_INFO( "時", JP_PROP_TIME,        JP_UNIT_NONE    ),
  160.     JP_UNIT_INFO( "固", JP_PROP_UNIQUE,        JP_UNIT_NONE    ),
  161.     JP_UNIT_INFO( "量", JP_PROP_VOLUME,        JP_UNIT_NONE    ),
  162.     JP_UNIT_INFO( "衣", JP_PROP_CLOTH,        JP_UNIT_CHAKU    ),
  163.     JP_UNIT_INFO( "食", JP_PROP_FOOD,        JP_UNIT_NONE    ),
  164.     JP_UNIT_INFO( "飲", JP_PROP_DRINK,        JP_UNIT_NONE    ),
  165.     JP_UNIT_INFO( "乗", JP_PROP_VEHICLE,    JP_UNIT_NONE    ),
  166.     JP_UNIT_INFO( "音", JP_PROP_SOUND,        JP_UNIT_NONE    ),
  167.     JP_UNIT_INFO( "勉", JP_PROP_STUDY,        JP_UNIT_NONE    ),
  168.     JP_UNIT_INFO( "敬", JP_PROP_TITLE,        JP_UNIT_NONE    ),
  169.     JP_UNIT_INFO( "姓", JP_PROP_FAMILY,        JP_UNIT_HITO    ),
  170.     JP_UNIT_INFO( "材", JP_PROP_MATERIAL,    JP_UNIT_NONE    ),
  171.     JP_UNIT_INFO( "天", JP_PROP_WEATHER,    JP_UNIT_NONE    ),
  172.     JP_UNIT_INFO( "台", JP_PROP_NONE,        JP_UNIT_DAI        ),
  173.     JP_UNIT_INFO( "本", JP_PROP_NONE,        JP_UNIT_HON        ),
  174.     JP_UNIT_INFO( "つ", JP_PROP_NONE,        JP_UNIT_TSU        ),
  175.     JP_UNIT_INFO( "個", JP_PROP_NONE,        JP_UNIT_KO        ),
  176.     JP_UNIT_INFO( "冊", JP_PROP_NONE,        JP_UNIT_SATU    ),
  177.     JP_UNIT_INFO( "匹", JP_PROP_NONE,        JP_UNIT_HIKI    ),
  178.     JP_UNIT_INFO( "頭", JP_PROP_NONE,        JP_UNIT_TOU        ),
  179.     JP_UNIT_INFO( "羽", JP_PROP_NONE,        JP_UNIT_WA        ),
  180.     JP_UNIT_INFO( "単", JP_PROP_UNIT,        JP_UNIT_UNIT    ),    // 単位 metre, gramme, franc, ...
  181.     JP_UNIT_INFO( "枚", JP_PROP_NONE,        JP_UNIT_MAI        ),
  182.     JP_UNIT_INFO( "日", JP_PROP_DATE,        JP_UNIT_NONE    ),
  183.     JP_UNIT_INFO( "感", JP_PROP_EMOTION,    JP_UNIT_NONE    ),
  184.     JP_UNIT_INFO( "体",    JP_PROP_BODY,        JP_UNIT_NONE    ),
  185.     JP_UNIT_INFO( "植",    JP_PROP_PLANT,        JP_UNIT_HON        ),
  186.     JP_UNIT_INFO( "部",    JP_PROP_PARTIAL,    JP_UNIT_NONE    ),    
  187.     JP_UNIT_INFO( "問", JP_PROP_QUESTION,    JP_UNIT_NONE    ),
  188.     JP_UNIT_INFO( "否", JP_PROP_NEGATIVE,    JP_UNIT_NONE    ),
  189.     JP_UNIT_INFO( "受",    JP_PROP_PASSIVE,    JP_UNIT_NONE    ),
  190.     JP_UNIT_INFO( "",    JP_PROP_NONE,        JP_UNIT_NONE    ),
  191. };
  192.  
  193. JP_KIND_INFO    jpKindInfoTable[] = 
  194. {
  195.     {    "う", JP_KIND_GODAN },
  196.     {    "く", JP_KIND_GODAN_KA },
  197.     {    "す", JP_KIND_GODAN_SA },
  198.     {    "つ", JP_KIND_GODAN_TA },
  199.     {    "ぬ", JP_KIND_GODAN_NA },
  200.     {    "ふ", JP_KIND_GODAN_HA },
  201.     {    "む", JP_KIND_GODAN_MA },
  202. //    {    "う", JP_KIND_GODAN_YA },
  203.     {    "る", JP_KIND_GODAN_RA },
  204. //    {    "う", JP_KIND_GODAN_WA },
  205.     {    "ぐ", JP_KIND_GODAN_GA },
  206.     {    "ず", JP_KIND_GODAN_ZA },
  207.     {    "づ", JP_KIND_GODAN_DA },
  208.     {    "ぶ", JP_KIND_GODAN_BA },
  209.     {    "い", JP_KIND_IRU  },
  210.     {    "き", JP_KIND_KIRU },
  211.     {    "し", JP_KIND_SIRU },
  212.     {    "ち", JP_KIND_TIRU },
  213.     {    "に", JP_KIND_NIRU },
  214.     {    "ひ", JP_KIND_HIRU },
  215.     {    "み", JP_KIND_MIRU },
  216. //    {    "い", JP_KIND_YIRU },
  217.     {    "り", JP_KIND_RIRU },
  218. //    {    "い", JP_KIND_WIRU },
  219.     {    "ぎ", JP_KIND_GIRU },
  220.     {    "じ", JP_KIND_ZIRU },
  221.     {    "ぢ", JP_KIND_DIRU },
  222.     {    "び", JP_KIND_BIRU },
  223.     {    "え", JP_KIND_ERU  },
  224.     {    "け", JP_KIND_KERU },
  225.     {    "せ", JP_KIND_SERU },
  226.     {    "て", JP_KIND_TERU },
  227.     {    "ね", JP_KIND_NERU },
  228.     {    "へ", JP_KIND_HERU },
  229.     {    "め", JP_KIND_MERU },
  230. //    {    "え", JP_KIND_YERU },
  231.     {    "れ", JP_KIND_RERU },
  232. //    {    "え", JP_KIND_WERU },
  233.     {    "げ", JP_KIND_GERU },
  234.     {    "ぜ", JP_KIND_ZERU },
  235.     {    "で", JP_KIND_DERU },
  236.     {    "べ", JP_KIND_BERU },
  237.     {    "だ", JP_KIND_DA    },
  238.     {    "カ", JP_KIND_KAHEN },
  239.     {    "サ", JP_KIND_SAHEN },
  240.     {    "シ", JP_KIND_SAHEN2 },
  241.     {    "形", JP_KIND_KEIYOSHI },
  242.     {    "動", JP_KIND_KEIYODOSHI },
  243.     {    "連", JP_KIND_RENTAISHI },
  244.     {    "副", JP_KIND_ADVERB },
  245.     {    "",        JP_KIND_NONE }    // End Mark
  246. };
  247.  
  248. //
  249. // 日本語訳の情報を得る
  250. //
  251. void
  252. GetJpInfo(FR_PART *frPart, JP_PROP *jpProp, JP_KIND *jpKind, JP_UNIT *jpUnit, FR_LOCATION *location)
  253. {
  254.     while(TRUE) {
  255.         if(Amatch(",") || *tokenPtr == '\n' || *tokenPtr == '\0') {
  256.             break;
  257.         } else if(Amatch("AI")) {
  258.             *frPart = FR_PART_PREPOSIT_A_INF;
  259.         } else if(Amatch("<@>")) {
  260.             *frPart = FR_PART_PREPOSIT_A;
  261.         } else if(Amatch("<avec>")) {
  262.             *frPart = FR_PART_PREPOSIT_AVEC;
  263.         } else if(Amatch("DI")) {
  264.             *frPart = FR_PART_PREPOSIT_DE_INF;
  265.         } else if(Amatch("<de>")) {
  266.             *frPart = FR_PART_PREPOSIT_DE;
  267.         } else if(Amatch("PI")) {
  268.             *frPart = FR_PART_PREPOSIT_POUR_INF;
  269.         } else if(Amatch("<pour>")) {
  270.             *frPart = FR_PART_PREPOSIT_POUR;
  271.         } else if(Amatch("<que>")) {
  272.             *frPart = FR_PART_SENTENCE_QUE;
  273. /*        } else if(Amatch("K")) {
  274.             *jpKind = (JP_KIND)(*jpKind | JP_KIND_KEIYOSHI);
  275.         } else if(Amatch("D")) {
  276.             *jpKind = (JP_KIND)(*jpKind | JP_KIND_KEIYODOSHI);
  277.         } else if(Amatch("M")) {
  278.             *jpKind = (JP_KIND)(*jpKind | JP_KIND_KEIYODOSHI2);
  279. */        } else if(Amatch("B")) {
  280.             *location = (FR_LOCATION)(*location & ~(FR_LOCATION_BEHIND));
  281.             *location = (FR_LOCATION)(*location | FR_LOCATION_FRONT);
  282.         } else {
  283.             BOOL    hit = FALSE;
  284.             for(JP_UNIT_INFO *q = jpUnitInforTable; *(q->cmd); q++) {
  285.                 if(Amatch((char *)q->cmd)) {
  286.                     *jpProp |= q->jpProp;
  287.                     *jpUnit = (JP_UNIT)(*jpUnit | q->jpUnit);
  288.                     hit = TRUE;
  289.                 }
  290.             }
  291.             for(JP_KIND_INFO *r = jpKindInfoTable; *(r->cmd); r++) {
  292.                 if(Amatch((char *)r->cmd)) {
  293.                     *jpKind = r->jpKind;
  294.                     hit = TRUE;
  295.                 }
  296.             }
  297.             if(hit == FALSE) {
  298.                 SyntaxError();
  299.                 return;
  300.             }
  301.         }
  302.     }
  303. }
  304.  
  305. //
  306. // フランス語の情報を得る
  307. //
  308. void
  309. GetFrInfo(FR_ATTRIB *frAttrib, FR_CHANGE *frChange)
  310. {
  311.     *frAttrib = FR_ATTRIB_NONE;
  312.     // 規則変化で女性形・複数形が作れる
  313.     *frChange = (FR_CHANGE)(FR_CHANGE_FEMALE | FR_CHANGE_PLURAL);
  314.  
  315.     while(TRUE) {
  316.         if(Amatch(",") || *tokenPtr == '\n' || *tokenPtr == '\0') {
  317.             break;
  318.         } else if(Amatch("F")) {    // 女性名詞
  319.             *frAttrib = (FR_ATTRIB)(*frAttrib | FR_ATTRIB_FEMALE);
  320.         } else if(Amatch("M")) {    // 男性名詞
  321.             *frAttrib = (FR_ATTRIB)(*frAttrib | FR_ATTRIB_MALE);
  322.         } else if(Amatch("P")) {    // 集合名詞など複数形
  323.             *frAttrib = (FR_ATTRIB)(*frAttrib & (~FR_ATTRIB_SINGLE));
  324.             *frAttrib = (FR_ATTRIB)(*frAttrib | FR_ATTRIB_PLURAL);
  325.         } else if(Amatch("f")) {    // 規則変化で女性形が作<れない>
  326.             *frChange = (FR_CHANGE)(*frChange & (~FR_CHANGE_FEMALE));
  327.         } else if(Amatch("d")) {    // 規則変化で形容詞が作れる
  328.             *frChange = (FR_CHANGE)(*frChange | FR_CHANGE_ADJECTIVE);
  329.         } else if(Amatch("p")) {    // 規則変化で複数形が作<れない>
  330.             *frChange = (FR_CHANGE)(*frChange & (~FR_CHANGE_PLURAL));
  331.         } else if(Amatch("v")) {    // 規則変化で副詞が作れる
  332.             *frChange = (FR_CHANGE)(*frChange | FR_CHANGE_ADVERB);
  333.         } else {
  334.             SyntaxError();
  335.             break;
  336.         }
  337.     }
  338. }
  339.  
  340. //
  341. // 形容詞をload
  342. //
  343. void
  344. LoadAdjectiveTable(char *fn)
  345. {
  346.     FILE    *fp;
  347.     ADJECTIVE    *adjective;
  348.  
  349.     fp = fopen(fn, "rt");
  350.     if((int)fp <= 0) {
  351.         PrintInternalError( "Can not open <%s>\nThis file must be in the same directory.", fn);
  352.         exit(-1);
  353.     } else {
  354.         while(TRUE) {
  355.             fgets(inputBuff, sizeof(inputBuff), fp);
  356.             if(feof(fp))    break;
  357.             tokenPtr = inputBuff;
  358.             adjective = GetAdjectiveWord();
  359.             SetAdjectiveWord(adjective);
  360.         }
  361.     }
  362.     fclose(fp);
  363. }
  364.  
  365.  
  366. ADJECTIVE
  367. *GetAdjectiveWord(void)
  368. {
  369.     int        i;
  370.     FR_PART        dummyFrPart;
  371.     JP_UNIT        dummyJpUnit;
  372.     JP_KIND        dummyJpKind;
  373.     FR_LOCATION    dummyLocation;
  374.  
  375.     ADJECTIVE    *adj = (ADJECTIVE *)MyAlloc(sizeof(ADJECTIVE));
  376.     if(adj == NULL)    goto MemOver;
  377.  
  378.     adj->left = adj->right = NULL;
  379.     adj->french = NewString();
  380.  
  381.     if(adj->french == NULL)    goto MemOver;
  382.  
  383.     GetFrInfo(&(adj->frAttrib), &(adj->frChange));
  384.  
  385.     if(adj->frChange & FR_CHANGE_PLURAL) {
  386.         FR_CHANGE frChange = GetPluralType(adj->french);
  387.         if(frChange == FR_CHANGE_NONE) {    // 単複同形名詞
  388.             adj->frAttrib = (FR_ATTRIB)(adj->frAttrib | FR_ATTRIB_PLURAL);
  389.         } else {
  390.             adj->frChange = (FR_CHANGE)(adj->frChange | frChange);
  391.         }
  392.     }
  393.  
  394.     adj->proposed = CountComma(tokenPtr)/5+1;
  395.     adj->jpAdjective = (JP_ADJECTIVE*)MyAlloc(sizeof(JP_ADJECTIVE) *adj->proposed); 
  396.     if(adj->jpAdjective == NULL)    goto MemOver;
  397.  
  398.     for(i = 0; i < adj->proposed; i++) {
  399.         adj->jpAdjective[i].pJpProp  = JP_PROP_NONE;
  400.         adj->jpAdjective[i].myJpProp = JP_PROP_NONE;
  401.         adj->jpAdjective[i].location = FR_LOCATION_BEHIND;
  402.  
  403.         // Parentの情報
  404.         GetJpInfo(&dummyFrPart,
  405.                   &(adj->jpAdjective[i].pJpProp),
  406.                   &dummyJpKind,
  407.                   &dummyJpUnit,
  408.                   &(adj->jpAdjective[i].location));
  409.         // Childの情報(もし、あれば)
  410.         adj->jpAdjective[i].cFrPart     = FR_PART_NONE;
  411.         adj->jpAdjective[i].cJpProp     = JP_PROP_NONE;
  412.         GetJpInfo(&(adj->jpAdjective[i].cFrPart),
  413.                   &(adj->jpAdjective[i].cJpProp),
  414.                   &dummyJpKind,
  415.                   &dummyJpUnit,
  416.                   &dummyLocation);
  417.         if(adj->jpAdjective[i].cJpProp == JP_PROP_NONE)
  418.             adj->jpAdjective[i].cJpProp = JP_PROP_ALL;
  419.  
  420.         adj->jpAdjective[i].japanese = NewJpWord(&(adj->jpAdjective[i].jpKind));
  421.         dummyJpKind = JP_KIND_NONE;
  422.  
  423.         GetJpInfo(&dummyFrPart,
  424.                   &(adj->jpAdjective[i].myJpProp),
  425.                   &(adj->jpAdjective[i].jpKind),
  426.                   &dummyJpUnit,
  427.                   &dummyLocation);
  428.         if(Amatch(",") || IsNullField())
  429.             adj->jpAdjective[i].opposite = NULL;
  430.         else
  431.             adj->jpAdjective[i].opposite = NewString();
  432.  
  433.         // default settings
  434.         if(adj->jpAdjective[i].myJpProp == JP_PROP_NONE)
  435.             adj->jpAdjective[i].myJpProp = JP_PROP_CONDITION;
  436.         if(adj->jpAdjective[i].pJpProp == JP_PROP_NONE)
  437.             adj->jpAdjective[i].pJpProp = JP_PROP_ALL;
  438.         if(adj->jpAdjective[i].location == FR_LOCATION_NONE)
  439.             adj->jpAdjective[i].location = FR_LOCATION_FRONT;
  440.     }
  441.     // これ以上の候補はない
  442. //    adj->jpAdjective[i].pJpProp = JP_PROP_ALL;
  443.     return(adj);
  444. MemOver:
  445.     PrintInternalError( "Out Of Memory!!\n");
  446.     return(NULL);
  447. }
  448.  
  449. //
  450. // 形容詞を辞書に登録
  451. //
  452. void
  453. SetAdjectiveWord(ADJECTIVE *newAdjective)
  454. {
  455.     if(adjectiveTable == NULL) {    // 最初の単語
  456.         adjectiveTable = newAdjective;
  457.         return;
  458.     }
  459.  
  460.     ADJECTIVE    *p = adjectiveTable;
  461.     while(p) {
  462.         if(strcmp(newAdjective->french, p->french) < 0)    {
  463.             if(p->left) { p = p->left; continue; }
  464.             else        { p->left = newAdjective; break;    }
  465.         } else {
  466.             if(p->right){ p = p->right; continue; }
  467.             else        { p->right = newAdjective; break; }
  468.         }
  469.     }
  470. }
  471.  
  472. //
  473. // 副詞をload
  474. //
  475. void
  476. LoadAdverbTable(char *fn)
  477. {
  478.     FILE    *fp;
  479.  
  480.     fp = fopen(fn, "rt");
  481.     if((int )fp <= 0) {
  482.         PrintInternalError( "Can not open <%s>\nThis file must be in the same directory.", fn);
  483.         exit(-1);
  484.     } else {
  485.         while(TRUE) {
  486.             ADVERB    *adverb;
  487.             fgets(inputBuff, sizeof(inputBuff), fp);
  488.             if(feof(fp))    break;
  489.             tokenPtr = inputBuff;
  490.             adverb = GetAdverbWord();
  491.             SetAdverbWord(adverb);
  492.         }
  493.     }
  494.     fclose(fp);
  495. }
  496.  
  497. ADVERB
  498. *GetAdverbWord(void)
  499. {
  500.     int        i;
  501.     ADVERB        *adverb = (ADVERB *)MyAlloc(sizeof(ADVERB));
  502.     FR_PART        dummyFrPart;
  503.     FR_LOCATION    dummyLocation;
  504.     JP_KIND        dummyJpKind;
  505.     JP_UNIT        dummyJpUnit;
  506.  
  507.     adverb->left = adverb->right = NULL;
  508.     adverb->french = NewString();
  509.  
  510.     adverb->proposed = CountComma(tokenPtr)/4+1;
  511.     adverb->jpAdverb = (JP_ADVERB*)MyAlloc(sizeof(JP_ADVERB) * adverb->proposed); 
  512.  
  513.     for(i = 0; i < adverb->proposed; i++) {
  514.         adverb->jpAdverb[i].pJpProp = JP_PROP_NONE;
  515.         adverb->jpAdverb[i].myJpProp = JP_PROP_NONE;
  516.         adverb->jpAdverb[i].jpKind  = JP_KIND_NONE;
  517.  
  518.         GetJpInfo(&dummyFrPart,
  519.                   &(adverb->jpAdverb[i].pJpProp),
  520.                   &dummyJpKind,
  521.                   &dummyJpUnit,
  522.                   &dummyLocation);
  523.         // default settings
  524.         if(adverb->jpAdverb[i].pJpProp == JP_PROP_NONE)
  525.             adverb->jpAdverb[i].pJpProp = JP_PROP_ALL;
  526.  
  527.         adverb->jpAdverb[i].japanese = NewString();
  528.  
  529.         GetJpInfo(&dummyFrPart,
  530.                   &(adverb->jpAdverb[i].myJpProp),
  531.                   &(adverb->jpAdverb[i].jpKind),
  532.                   &dummyJpUnit,
  533.                   &dummyLocation);
  534.         // default settings
  535.         if(adverb->jpAdverb[i].myJpProp == JP_PROP_NONE)
  536.             adverb->jpAdverb[i].myJpProp = JP_PROP_CONDITION;
  537. #if 0
  538.         // default settings
  539.         if(adverb->jpAdverb[i].jpKind == JP_KIND_NONE)
  540.             adverb->jpAdverb[i].jpKind = JP_KIND_ADVERB;
  541. #endif
  542.         if(Amatch(",") || IsNullField())
  543.             adverb->jpAdverb[i].opposite = NULL;
  544.         else
  545.             adverb->jpAdverb[i].opposite = NewString();
  546.     }
  547.     // これ以上の候補はない
  548. //    adverb->jpAdverb[i].pJpProp = JP_PROP_ALL;
  549.     return(adverb);
  550. }
  551.  
  552. //
  553. // 形容詞を辞書に登録
  554. //
  555. void
  556. SetAdverbWord(ADVERB *newAdverb)
  557. {
  558.     if(adverbTable == NULL) {    // 最初の単語
  559.         adverbTable = newAdverb;
  560.         return;
  561.     }
  562.  
  563.     ADVERB    *p = adverbTable;
  564.     while(p) {
  565.         if(strcmp(newAdverb->french, p->french) < 0)    {
  566.             if(p->left) { p = p->left; continue; }
  567.             else        { p->left = newAdverb; break;    }
  568.         } else {
  569.             if(p->right){ p = p->right; continue; }
  570.             else        { p->right = newAdverb; break; }
  571.         }
  572.     }
  573. }
  574.  
  575. //
  576. // 語尾から複数形を判定する
  577. //
  578. FR_CHANGE
  579. GetPluralType(char *french)
  580. {
  581.     int    len = strlen(french);
  582.  
  583.     if(french[len-1] == 's'    // 単複同形名詞
  584.     || french[len-1] == 'x'
  585.     || french[len-1] == 'z') {
  586.         return(FR_CHANGE_NONE);
  587.     } else if(!strcmp(&french[len-3], "eau")
  588.     || !strcmp(&french[len-2], "au")
  589.     || !strcmp(&french[len-2], "eu")) {
  590.         return((FR_CHANGE)(FR_CHANGE_PLURAL | FR_CHANGE_PLURAL_X));
  591.     } else if(!strcmp(&french[len-2], "al")) {
  592.         french[--len] = '\0';    // 'l'と 'ux'を取り替えて複数形を作る journal -> journaux
  593.         return((FR_CHANGE)(FR_CHANGE_PLURAL | FR_CHANGE_PLURAL_AUX));
  594.     } else {
  595.         return(FR_CHANGE_PLURAL);
  596.     }
  597. }
  598.  
  599. //
  600. // 文字列を「,」まで切り取る + 語尾を推定 + 語尾をカット
  601. //
  602. char
  603. *NewJpWord(JP_KIND *jpKind)
  604. {
  605.     char    tmp[100];
  606.     char    *p = tmp;
  607.  
  608.     while(*(unsigned char *)tokenPtr > ' ' && *tokenPtr != ',') {
  609.         *p++ = *tokenPtr++;
  610.     }
  611.     *p = '\0';
  612.     if(*tokenPtr == ',') tokenPtr++;
  613.  
  614.     if(CmpWordTail(tmp, "いる"))        *jpKind = JP_KIND_IRU;
  615.     else if(CmpWordTail(tmp, "れた"))    *jpKind = JP_KIND_SHIMOICHI2_RA;
  616.     else if(CmpWordTail(tmp, "んだ"))    *jpKind = JP_KIND_SHIMOICHI2_N;
  617.     else if(CmpWordTail(tmp, "した"))    *jpKind = JP_KIND_SAHEN2;
  618.     else if(CmpWordTail(tmp, "い"))        *jpKind = JP_KIND_KEIYOSHI;
  619.     else if(CmpWordTail(tmp, "な"))        *jpKind = JP_KIND_KEIYODOSHI;
  620.     else if(CmpWordTail(tmp, "だ"))        *jpKind = JP_KIND_KEIYODOSHI;
  621.     else if(CmpWordTail(tmp, "の"))        *jpKind = JP_KIND_RENTAISHI;
  622.     else    *jpKind = JP_KIND_NONE;
  623.  
  624.     int    len = strlen(tmp);
  625.     char *ret = (char *)MyAlloc(len + 1);
  626.     strncpy(ret, tmp, len);
  627.     ret[len] = '\0';
  628.     return(ret);
  629. }
  630.  
  631. //
  632. // 文字列を「,」まで切り取る
  633. //
  634. char
  635. *NewString(void)
  636. {
  637.     int        len;
  638.     char    *savPtr = tokenPtr;
  639.     char    *ret;
  640.  
  641.     // 単語の数を数える
  642.     while(*tokenPtr && *tokenPtr++ != ',');
  643.  
  644.     len = tokenPtr - savPtr - 1;
  645.     if(len < 0)    len = 0;
  646.     ret = (char *)MyAlloc(len + 1);
  647.     if(ret) {
  648.         strncpy(ret, savPtr, len);
  649.         ret[len] = '\0';
  650.     }
  651.     return(ret);
  652. }
  653.  
  654.  
  655. //
  656. // 文字列中の「,」を数える
  657. int
  658. CountComma(char *s)
  659. {
  660.     int    cnt = 0;
  661.     while(*s) {
  662.         if(*s++ == ',') cnt++;
  663.     }
  664.     return(cnt);
  665. }
  666.  
  667.  
  668. //
  669. // 文字列の語尾を比較
  670. //
  671. BOOL
  672. CmpWordTail(char *s, char *t)
  673. {
  674.     int    l1 = strlen(s);
  675.     int    l2 = strlen(t);
  676.  
  677.     if(l1 > l2
  678.     && !strcmp(&s[l1-l2], t)) {
  679.         s[l1-l2] = '\0';
  680.         return(TRUE);
  681.     }
  682.     return(FALSE);
  683. }
  684.  
  685. //
  686. //
  687. //
  688. BOOL
  689. IsNullField(void)
  690. {
  691.     switch(*tokenPtr) {
  692.     case '\0':
  693.     case '\r':
  694.     case '\n':
  695.     case ',':
  696.         return(TRUE);
  697.     default:
  698.         return(FALSE);
  699.     }
  700. }
  701.  
  702. //
  703. //
  704. //
  705. void
  706. SyntaxError(void )
  707. {
  708.     char    lpszBuff[300];
  709.  
  710.     strcpy(lpszBuff, inputBuff);            // 改行文字は含まれている
  711.  
  712.     char    *q = &lpszBuff[strlen(inputBuff)];
  713.  
  714.     for(char *p = inputBuff; p < tokenPtr; p++)
  715.         *q++ = ' ';
  716.     strcpy(q, "^ Error");
  717.  
  718.     PrintInternalError(lpszBuff);
  719. }